package string.sequentialstring;

import string.inter.CustString;

public class SeqString implements CustString {
    private int maxSize = 127;
    private char[] arr;
    private int length = 0;

    public SeqString() {
        arr = new char[maxSize];
    }

    public SeqString(int maxSize) {
        this.maxSize = maxSize;
        arr = new char[maxSize];
    }

    public SeqString(char[] arr) {
        this();
        assign(arr);
    }

    public SeqString(int maxSize, char[] arr) {
        this(maxSize);
        assign(arr);
    }

    @Override
    public CustString strCopy() {
        CustString copyStr = new SeqString(maxSize);
        copyStr.assign(arr);
        return copyStr;
    }

    @Override
    public void clearString() {
        this.arr = new char[maxSize];
    }

    @Override
    public boolean stringEmpty() {
        return this == null || length == 0;
    }

    @Override
    public int strCompare(CustString string) {
        if (string.stringEmpty() || this.stringEmpty()) {
            return 0;
        }
        int n = string.strLength() > this.strLength() ? this.strLength() : string.strLength();
        for (int i = 0; i < n; i++) {
            if (string.charAt(i) != this.charAt(i)) {
                return string.charAt(i) - this.charAt(i);
            }
        }
        if (this.strLength() == string.strLength()) {
            return 0;
        }
        return string.strLength() > this.strLength() ? 1 : -1;
    }

    @Override
    public CustString concat(CustString s1, CustString s2) {
        char[] temChs = new char[s1.strLength() + s2.strLength()];
        for (int i = 0; i < s1.strLength(); i++) {
            temChs[i] = s1.charAt(i);
        }
        for (int i = 0; i < s2.strLength(); i++) {
            temChs[s1.strLength() + i] = s2.charAt(i);
        }
        CustString custString = new SeqString();
        custString.assign(temChs);
        return custString;
    }

    @Override
    public int index(CustString s, int pos) {
        return kmp(pos, s);
    }

    @Override
    public CustString replace(CustString source, CustString target) {
        int pos = index(source, 0); // 开始匹配的位置
        int n = target.strLength() - source.strLength();
        while (pos != -1 && pos <= this.length && pos + source.strLength() <= this.length) {
            if (n > 0) {
                for (int i = length - 1; i > pos + source.strLength(); i--) {
                    arr[i + n + 1] = arr[i];
                }
            } else if (n < 0) {
                for (int i = pos + n + 1; i < length; i++) {
                    arr[i + n] = arr[i];
                }
            }
            int q = pos;
            for (int i = 0; i < target.strLength(); i++) {
                arr[q + i] = target.charAt(i);
            }
            pos = index(source, pos + (target.strLength() + 1));
            length += n;
        }
        return this;
    }

    @Override
    public void strInsert(CustString s, int pos) {
        if (pos < 0 || pos > length || s.strLength() + this.length > maxSize) {
            System.out.println("字符串插入失败插入失败");
            return;
        }
        // 字符后移
        for (int i = length; i >= pos; i--) {
            arr[s.strLength() + i] = arr[i];
        }
        // 字符串放入相应位置
        for (int i = 0; i < s.strLength(); i++) {
            arr[pos + i] = s.charAt(i);
            length++;
        }
    }

    @Override
    public CustString strDelete(int pos, int len) {
        if (pos < 0 || pos > length || pos + len > length) {
            System.out.println("删除字符串失败");
        }

        int strLen = strLength();
        for (int i = pos + len; i < strLen; i++) {
            arr[i - len] = arr[i];
        }
        length -= len;
        return this;
    }

    @Override
    public void assign(char[] chs) {
        length = 0;
        for (int i = 0; i < chs.length; i++) {
            arr[i] = chs[i];
            length++;
        }
    }

    @Override
    public char charAt(int i) {
        return arr[i];
    }

    @Override
    public int strLength() {
        return length;
    }

    @Override
    public void strReverse() {
        char temp;
        for (int i = 0; i < this.strLength() / 2; i++) {
            temp = arr[i];
            arr[i] = arr[this.strLength() - i - 1];
            arr[this.strLength() - i - 1] = temp;
        }
    }

    @Override
    public void printStr() {
        for (int i = 0; i < length; i++) {
            System.out.print(arr[i]);
        }
        System.out.println();
    }
}
